home *** CD-ROM | disk | FTP | other *** search
/ FishMarket 1.0 / FishMarket v1.0.iso / fishies / 151-175 / disk_166 / autograf / dograf.c < prev    next >
C/C++ Source or Header  |  1992-05-06  |  11KB  |  502 lines

  1. /*
  2.      dograf.c : subroutine to draw graph
  3.  
  4.      By Joel Swank September 3, 1988
  5.      Version 1.0
  6.  
  7.      */
  8.  
  9. #include <intuition/intuition.h>
  10. #include <intuition/intuitionbase.h> 
  11. #include <graphics/gfxbase.h> 
  12. #include <graphics/gfx.h> 
  13. #include <graphics/gfxmacros.h> 
  14. #include <graphics/display.h> 
  15. #include <graphics/text.h> 
  16. #include <ctype.h> 
  17.  
  18. /*************
  19.  
  20.  *  Hooks to the rest of the program
  21.  
  22.  *************/
  23.  
  24. extern char nodatamsg[];
  25. extern char tempbuf[];
  26. extern char filename[];
  27.  
  28. #define MenuList1 Menu1
  29. extern struct Menu Menu1;
  30. extern struct Window    *Wind;
  31. extern struct RastPort *rp;
  32. extern struct IntuiText oktxt;
  33. extern int numrecs;
  34. extern int fileread;
  35.  
  36. /* save areas for graphing data */
  37. int yrsave[1000];        /* save year of each entry */
  38. float costsave[1000];    /* save averaged cost data of each entry */
  39. float milesave[1000];    /* save averaged mile data of each entry */
  40. float pricesave[1000];    /* save price data of each entry */
  41. float odsave[1000];        /* save odometer data of each entry */
  42. float rawcost[1000];    /* save cost data of each entry */
  43.  
  44. /* flags for which grafs to display */
  45. extern int cpm;
  46. extern int ppg;
  47. extern int mpg;
  48.  
  49. extern int syr;        /* for requested start year */
  50. extern int eyr;        /* for requested end year */
  51.  
  52. /* Local data */
  53.  
  54. /*
  55.  *    Data describing the NEXT gadget
  56.  *
  57.  */
  58.  
  59. SHORT BorderVectorsM[] = {
  60.     0,0,
  61.     42,0,
  62.     42,15,
  63.     0,15,
  64.     0,0
  65. };
  66. struct Border BorderM = {
  67.     -2,-1,    /* XY origin relative to container TopLeft */
  68.     1,2,JAM2,    /* front pen, back pen and drawmode */
  69.     5,    /* number of XY vectors */
  70.     BorderVectorsM,    /* pointer to XY vectors */
  71.     NULL    /* next border in list */
  72. };
  73.  
  74. struct IntuiText ITextM = {
  75.     1,2,JAM2,    /* front and back text pens, drawmode and fill byte */
  76.     5,4,    /* XY origin relative to container TopLeft */
  77.     NULL,    /* font pointer or NULL for default */
  78.     (UBYTE *)"NEXT",    /* pointer to text */
  79.     NULL    /* next IntuiText structure */
  80. };
  81.  
  82. struct Gadget GadgetM = {
  83.     NULL,    /* next gadget */
  84.     5,142,    /* origin XY of hit box relative to window TopLeft */
  85.     39,14,    /* hit box width and height */
  86.     NULL,    /* gadget flags */
  87.     RELVERIFY,    /* activation flags */
  88.     BOOLGADGET,    /* gadget type flags */
  89.     (APTR)&BorderM,    /* gadget border or image to be rendered */
  90.     NULL,    /* alternate imagery for selection */
  91.     &ITextM,    /* first IntuiText structure */
  92.     0L,    /* gadget mutual-exclude long word */
  93.     NULL,    /* SpecialInfo structure */
  94.     NULL,    /* user-definable data */
  95.     NULL    /* pointer to user-definable data */
  96. };
  97.  
  98. /*
  99.  *    Data describing the DONE gadget
  100.  *
  101.  */
  102.  
  103. SHORT BorderVectorsM1[] = {
  104.     0,0,
  105.     42,0,
  106.     42,15,
  107.     0,15,
  108.     0,0
  109. };
  110. struct Border BorderM1 = {
  111.     -2,-1,    /* XY origin relative to container TopLeft */
  112.     1,2,JAM2,    /* front pen, back pen and drawmode */
  113.     5,    /* number of XY vectors */
  114.     BorderVectorsM1,    /* pointer to XY vectors */
  115.     NULL    /* next border in list */
  116. };
  117.  
  118. struct IntuiText ITextM1 = {
  119.     1,2,JAM2,    /* front and back text pens, drawmode and fill byte */
  120.     5,4,    /* XY origin relative to container TopLeft */
  121.     NULL,    /* font pointer or NULL for default */
  122.     (UBYTE *)"DONE",    /* pointer to text */
  123.     NULL    /* next IntuiText structure */
  124. };
  125.  
  126. struct Gadget GadgetM1 = {
  127.     NULL,    /* next gadget */
  128.     5,50,    /* origin XY of hit box relative to window TopLeft */
  129.     39,14,    /* hit box width and height */
  130.     NULL,    /* gadget flags */
  131.     RELVERIFY,    /* activation flags */
  132.     BOOLGADGET,    /* gadget type flags */
  133.     (APTR)&BorderM1,    /* gadget border or image to be rendered */
  134.     NULL,    /* alternate imagery for selection */
  135.     &ITextM1,    /* first IntuiText structure */
  136.     0L,    /* gadget mutual-exclude long word */
  137.     NULL,    /* SpecialInfo structure */
  138.     NULL,    /* user-definable data */
  139.     NULL    /* pointer to user-definable data */
  140. };
  141.  
  142. float vertscale, horizscale;
  143. float max, min;        /* main max and min */
  144. float vsize;        /* verticle range */
  145. char textbuf[80];
  146. char titlebuf[80];
  147. int first = TRUE;
  148. int prevyear = 0;    /* detecting year change */
  149. long yval, xval;
  150.  
  151.  
  152. /*
  153.  *  draw_graph : draw requested graphs
  154.  */
  155. draw_graph()
  156. {
  157. long i;
  158.  
  159.     /* put up grafing gadgets */
  160.     AddGadget(Wind,&GadgetM,(USHORT) ~0);
  161.     AddGadget(Wind,&GadgetM1,(USHORT) ~0);
  162.  
  163.     /* disable all menu items except quit & print */
  164.     for (i=0; i<6; i++)
  165.         {
  166.         if (i == 4) continue; /* skip print */
  167.         OffMenu(Wind, (USHORT) SHIFTITEM(i));
  168.         }
  169.  
  170.     /* add mouse reporting to window */
  171.     ReportMouse(TRUE,Wind);
  172.  
  173.     /* do requested graphs */
  174.     while (1)
  175.           {
  176.         if (ppg)
  177.             {
  178.             if (do_graph('p') == 0) break;
  179.             }
  180.         if (cpm)
  181.             {
  182.             if (do_graph('c') == 0) break;
  183.             }
  184.         if (mpg)
  185.             {
  186.             if (do_graph('m') == 0) break;
  187.             }
  188.         }
  189.  
  190.     /* delete mouse reporting from window */
  191.     ReportMouse(FALSE,Wind);
  192.  
  193.     /* remove grafing gadgets */
  194.     RemoveGadget(Wind,&GadgetM);
  195.     RemoveGadget(Wind,&GadgetM1);
  196.  
  197.     /* enable all menu items */
  198.     for (i=0; i<7; i++)
  199.         {
  200.         if (!fileread)     /* if no file read . . . */
  201.             {
  202.             if (i=1) continue; /* skip draw and avgs */
  203.             if (i=2) continue;
  204.             }
  205.         OnMenu(Wind, (USHORT) SHIFTITEM(i));
  206.         }
  207.  
  208.     clr_grf();
  209.  
  210. }
  211.  
  212. /*
  213.  *  do_graph : draw one graph from 'mode' and stored data 
  214.  */
  215.  
  216. do_graph(mode)
  217. char mode; /* what to graph, p=price/gal, m=mile/gal, c=cost/mile */
  218. {
  219.  
  220.    struct IntuiMessage *msg;
  221.    char *patptr;
  222.    char *patpt2;
  223.    int i, ystart = -1;
  224.    int yend, year;
  225.    int mousex, mx, my;
  226.    register count;
  227.  
  228.     clr_grf();
  229.  
  230. /*************************************************
  231.      Select data, and find max/min
  232. *************************************************/
  233.  
  234.     max = 0;
  235.     min = 1e10;
  236.  
  237.     for (count=0; count<numrecs; count++)
  238.         {
  239.         year = yrsave[count];
  240.  
  241.         /* eliminate undesired years */
  242.  
  243.         if (eyr != -1)    
  244.               {
  245.             if (year > eyr) break;
  246.             }
  247.  
  248.         if (syr != -1)    
  249.               {
  250.             if (year < syr) continue;
  251.             }
  252.  
  253.         if (ystart == -1) ystart = count; /* remenber first */
  254.  
  255.  
  256.         /* find the max and min */
  257.         switch (mode)
  258.             {
  259.             case 'c':
  260.                 if (costsave[count] > 0)
  261.                     {
  262.                     if (costsave[count] > max) max = costsave[count];
  263.                     if (costsave[count] < min) min = costsave[count];
  264.                     }
  265.                 break;
  266.             case 'm':
  267.                 if(milesave[count] > 0)
  268.                     {
  269.                     if (milesave[count] > max) max = milesave[count];
  270.                     if (milesave[count] < min) min = milesave[count];
  271.                     }
  272.                 break;
  273.             case 'p':
  274.                 if (pricesave[count] > max) max = pricesave[count];
  275.                 if (pricesave[count] < min) min = pricesave[count];
  276.                 break;
  277.             }
  278.         }
  279.     yend = count;
  280.  
  281.     if (ystart == -1 || yend-ystart < 2)
  282.           {
  283.         AutoRequest(Wind,&nodatamsg,0L,&oktxt,0L,0L,300L,75L);
  284.         return(0);
  285.         }
  286.  
  287. /*************************************************
  288.      Calculate scale factors
  289. *************************************************/
  290.  
  291.         switch (mode)
  292.             {
  293.             case 'c':
  294.              strcpy(titlebuf,"Cents per Mile of Travel - File ");
  295.              break;
  296.             case 'm':
  297.              strcpy(titlebuf,"Miles per Gallon of Gasoline - File ");
  298.              break;
  299.             case 'p':
  300.              strcpy(titlebuf,"Dollars per Gallon of Gasoline - File ");
  301.              break;
  302.             }
  303.         vsize = (max - min) *1.1;
  304.         vertscale = 180.0/vsize;
  305.         horizscale = 570.0/ (float) (yend-ystart);
  306.  
  307.         strcat(titlebuf,filename);
  308.         SetWindowTitles(Wind,(UBYTE *) titlebuf, -1L);
  309.  
  310.     /*    if (!wb) 
  311.             {
  312.             printf("Vert scale = %f\n",vertscale);
  313.             printf("Horiz scale = %f\n",horizscale);
  314.             printf("Max = %f\n",max);
  315.             printf("Min = %f\n",min); 
  316.             } */
  317.  
  318.     /*************************************************
  319.             draw axis and vertical labels 
  320.     *************************************************/
  321.  
  322.         Move(rp,50L,15L);
  323.         Draw(rp,50L,183L);
  324.         Draw(rp,635,183L);
  325.         Move(rp,50L,105L);
  326.         Draw(rp,635,105L);
  327.         switch (mode)
  328.         {
  329.         case 'c':
  330.          patptr = "%5.2f";
  331.          patpt2 = "%5.2f cents/mi";
  332.          break;
  333.         case 'm':
  334.          patptr = "%5.2f";
  335.          patpt2 = "%5.2f mi/gal";
  336.          break;
  337.         case 'p':
  338.          patptr = "%5.3f";
  339.          patpt2 = "$%5.3f $/gal";
  340.          break;
  341.         }
  342.  
  343.     /* dray Y axis labels */
  344.     Move(rp,5L,18L);
  345.     sprintf(textbuf,patptr,min+vsize);
  346.     Text(rp,(UBYTE *)  textbuf, (long) strlen(textbuf));
  347.     Move(rp,5L,107L);
  348.     sprintf(textbuf,patptr,min+vsize/2);
  349.     Text(rp,(UBYTE *)  textbuf, (long) strlen(textbuf));
  350.     Move(rp,5L,187L);
  351.     sprintf(textbuf,patptr,min);
  352.     Text(rp,(UBYTE *)  textbuf, (long) strlen(textbuf));
  353.  
  354.     /* draw min and max values */
  355.     Move(rp,65L,30L);
  356.     sprintf(tempbuf,patpt2,max);
  357.     strcpy(textbuf,"Maximum = ");
  358.     strcat(textbuf,tempbuf);
  359.     Text(rp,(UBYTE *)  textbuf, (long) strlen(textbuf));
  360.     Move(rp,400L,170L);
  361.     sprintf(tempbuf,patpt2,min);
  362.     strcpy(textbuf,"Minimum = ");
  363.     strcat(textbuf,tempbuf);
  364.     Text(rp,(UBYTE *)  textbuf, (long) strlen(textbuf));
  365.  
  366.  
  367.  
  368. /*************************************************
  369.      MAIN Drawing Routine
  370. *************************************************/
  371.  
  372.     first = TRUE;
  373.     prevyear = 0;
  374.  
  375.     for (count=ystart ; count< yend; count++)
  376.       {
  377.  
  378.       year = yrsave[count];
  379.  
  380.       switch (mode)
  381.         {
  382.         case 'c':
  383.          if (costsave[count] == 0) yval = 0;
  384.          else yval = 180L - (long) ((costsave[count] - min) * vertscale);
  385.          break;
  386.  
  387.         case 'm':
  388.          if (milesave[count] == 0) yval = 0;
  389.          else yval = 180L - (long) ((milesave[count] - min) * vertscale);
  390.          break;
  391.  
  392.         case 'p':
  393.          yval = 180L - (long) ((pricesave[count] - min) * vertscale);
  394.          break;
  395.         }
  396.  
  397.       xval = (long) ( ((float) (count-ystart)) * horizscale)+50;
  398.  
  399.       if (yval != 0) /* don't draw zero entrys */
  400.           {
  401.           if (first)
  402.             {
  403.             Move(rp,xval, yval);
  404.             first = FALSE;
  405.             }
  406.           else Draw(rp,xval, yval);
  407.         }
  408.           /* printf("X=%ld, y=%ld\n",xval,yval);  */
  409.         if (year != prevyear) /* draw horiz label */
  410.         {
  411.         sprintf(textbuf,"%2d",year%100);
  412.         Move(rp,xval-TextLength(rp,textbuf, (long) strlen(textbuf))/2, 196L);
  413.         Text(rp,(UBYTE *)  textbuf, (long) strlen(textbuf));
  414.         Move(rp,xval,180L);    /* tick marks */
  415.         Draw(rp,xval,186L);
  416.         Move(rp,xval, yval);
  417.         }
  418.       prevyear = year;
  419.  
  420.       }
  421.  
  422.     /* redraw Gadgets */
  423.     RefreshGadgets(&GadgetM,Wind,0L);
  424.     RefreshGadgets(&GadgetM1,Wind,0L);
  425.  
  426. /*************************************************
  427.      WAIT for Close, NEXT or DONE Gadget and manage
  428.           the mouse reporting
  429. *************************************************/
  430.  
  431. while (1)
  432.     {
  433.     int menunum;
  434.     struct MenuItem *item, *ItemAddress();
  435.     Wait( 1L << Wind->UserPort->mp_SigBit);    /* wait on mesg */
  436.     while(msg = (struct IntuiMessage *) GetMsg(Wind->UserPort)) {
  437.         switch(msg->Class) {
  438.             case CLOSEWINDOW:
  439.                 ReplyMsg(msg);
  440.                 done(0);
  441.             case GADGETUP:
  442.                 ReplyMsg(msg);
  443.                 if (msg->IAddress == &GadgetM) return(1);  /* next graf */
  444.                 if (msg->IAddress == &GadgetM1) return(0); /* next file */
  445.                 continue;
  446.             case MENUPICK:    /* only print and quit are allowed */
  447.                 menunum = msg->Code;
  448.                 ReplyMsg(msg);
  449.                 while (menunum != MENUNULL)
  450.                     {
  451.                     switch(ITEMNUM(menunum))
  452.                         {
  453.                         case 4:
  454.                           do_print();
  455.                           break;
  456.                         case 6:
  457.                           done(0);
  458.                         }
  459.                     item = ItemAddress(&MenuList1,menunum);
  460.                     menunum = item->NextSelect;
  461.                     }
  462.                 continue;
  463.             case MOUSEMOVE:
  464.                 mx = msg->MouseX;
  465.                 my = msg->MouseY;
  466.                 ReplyMsg(msg);
  467.                 if (mx<50 || my>180) continue; /* off grafics area */
  468.                 if (mx != mousex)     /* if x has changed */
  469.                     {
  470.                     int index;
  471.                     float val;
  472.                     mousex =mx;
  473.                     /* get data value for current mouse X */
  474.                     index = (int) ( ((float) mx - 50) / horizscale) - ystart;
  475.                     if (index < ystart || index >= yend) continue;
  476.                     switch (mode)
  477.                         {
  478.                         case 'c':
  479.                           val = costsave[index];
  480.                            break;
  481.                         case 'm':
  482.                           val = milesave[index];
  483.                            break;
  484.                         case 'p':
  485.                           val = pricesave[index];
  486.                            break;
  487.                         }
  488.                     /* Draw the value */
  489.                     Move(rp,65L,20L);
  490.                     sprintf(tempbuf,patpt2,val);
  491.                     strcpy(textbuf,"Mouse @ ");
  492.                     strcat(textbuf,tempbuf);
  493.                     Text(rp,(UBYTE *)  textbuf, (long) strlen(textbuf));
  494.                     }
  495.                 continue;
  496.             }
  497.             ReplyMsg(msg);
  498.         }
  499.     }
  500. }
  501.  
  502.